# Copyright (c) 2020 Presto Labs Pte. Ltd.
# Author: jingyuan

from .base import OrderInfoTracker, ExportDataFrame
from ..on_log import OnLog
from collections import deque


class SubmitError(OrderInfoTracker, ExportDataFrame, OnLog):
  """
  checks the total number of submit errors during a rolling window
  """
  def __init__(self, window_period_sec=60, max_error_counts=5):
    """
    Args:
      window_period_sec: the maximum order lifetime limit in seconds
    """
    super().__init__()
    self.window_period = window_period_sec * 1e9
    self.max_error_counts = max_error_counts
    self.window = deque()

  def on_submit_reject(self, ts, currency, order_id, *args):
    self.window.append([ts, order_id, *args])
    while len(self.window) > 0 and ts - self.window[0][0] > self.window_period:
      self.window.popleft()
    if len(self.window) > self.max_error_counts:
      for ts, order_id, *args in self.window:
        names = ['error_code', 'exchange_error_code', 'error_msg']
        if order_id not in self.errors:
          self.errors[order_id] = {n: '' for n in names}
          self.errors[order_id]['order_id'] = order_id
        for i, name in enumerate(names):
          if str(args[i]) not in self.errors[order_id][name]:
            if len(self.errors[order_id][name]) > 0:
              self.errors[order_id][name] += f',{args[i]}'
            else:
              self.errors[order_id][name] += str(args[i])
        self.errors[order_id].update(self.order_info[order_id])
      self.window = deque()

  def to_df(self):
    df = super().to_df()
    df['submit_ts'] = df.submit_ts.dt.floor(freq=f'{int(self.window_period/1e9)}s')
    group = df.groupby(['submit_ts', 'error_msg', 'symbol',
                        'exchange_error_code', 'error_code', 'side'])
    df = group.count()[['qty']]
    df = df[df.groupby(['submit_ts', 'error_msg', 'symbol', 'exchange_error_code',
                        'error_code']).sum() > self.max_error_counts].dropna()
    df['qty'] = df['qty'].astype(int)
    return df.reset_index() \
             .rename(columns={
                 'submit_ts': 'window_start',
                 'qty': 'count'
             }) \
            .set_index('window_start') \
            .sort_values('count', ascending=False)
